home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / DNet / DGoClasses.cpp < prev    next >
Text File  |  1996-07-05  |  58KB  |  2,344 lines

  1. // DGopherClasses.cp
  2.  
  3. #include <ncbi.h>
  4. #include <dgg.h>
  5. #include <Dvibrant.h>
  6.  
  7. #include "DTCP.h"
  8. #include "DGopher.h"
  9. #include "DGoList.h"
  10. #include "DGoInit.h"
  11. #include "DGoPlus.h"
  12. #include "DGoClasses.h"
  13.  
  14. #include <DWindow.h>
  15. #include <DControl.h>
  16. #include <DDialogText.h>
  17. #include <DSendMailDialog.h>
  18. #include <DApplication.h>
  19. #include <DUtil.h>
  20.  
  21.  
  22. static const    long kReadMaxbuf1 = 1 * 1024;
  23. static const    long kMaxMemory     = 20 * 1024; // sure wish we could measure app free memory !!
  24.  
  25. const long    kGopherFileType     =
  26. #ifdef WIN_MSWIN
  27. 1234;
  28. #else
  29. 'IGo4'; // dup of SeqGopher.h const
  30. #endif
  31.  
  32.  
  33. //typedef    AppFile    *AppFilePtr;
  34.  
  35. // DFolderGopher -----------------------------
  36.  
  37.  
  38. void DFolderGopher::Initialize()
  39. {
  40.     fMacType= kGopherFileType; //TEXT  
  41.     fMacSire= kGopherFileType; //EDIT
  42.     fTransferType= kTransferBinary; //kTransferText; //text/lines or binary or none ?
  43.     fSaveToDisk= false;
  44.     fLaunch= false;
  45.     fCommand= cNewGopherFolder;
  46. }
  47.  
  48.  
  49.  
  50. DFolderGopher::DFolderGopher() 
  51. {
  52.     Initialize(); // my mistake -- 
  53.         // the base class Initialize() is called by DGopher() 
  54.         // this subclassed Initialize() must be called by this subclass constructor
  55.         // I should have known that and written this differently (IGopher() and IFolderGopher() ??)
  56. }
  57.  
  58. DFolderGopher::DFolderGopher( DFolderGopher* aGopher): DGopher(aGopher)
  59. {
  60.     //Initialize(); -- no DGopher(aGopher) will set fields way we want (i hope)
  61. }
  62.  
  63. DFolderGopher::DFolderGopher( char ctype, const char* link):
  64.     DGopher( ctype, link)
  65. {
  66.     Initialize();
  67. }
  68.  
  69.  
  70. DObject* DFolderGopher::Clone()
  71. {
  72.     DFolderGopher* aGopher= new DFolderGopher();
  73.     aGopher->CopyGopher( this);
  74.     return aGopher;
  75.     //return new DFolderGopher(this); << BAD, mangles this
  76. }
  77.  
  78. void DFolderGopher::DrawIcon( Nlm_RecT& area, short size)  
  79. {
  80.     gGopherIconID= kFolderIcon;
  81.     gIconSize= size;
  82.     DrawIconSub( area);
  83. }
  84.  
  85. const char* DFolderGopher::GetKindName() 
  86.     return "Folder";
  87. }
  88.  
  89.  
  90. void DFolderGopher::OpenQuery()
  91. {
  92.     if (fQueryPlus != NULL)  ;             // if wrapper has set this (for +ASK reply) leave it
  93.     else if (fIsPlus != kGopherPlusYes) fQueryPlus= NULL;
  94.     else {
  95.         // if sending viewform, can't send fQueryPlus !
  96.         if (fViewchoice) fQueryPlus= NULL;     // viewchoice conflicts w/ queryplus !!
  97.         else if (fShortFolder) fQueryPlus= "\t+"; // gopher+, call for short data
  98.         else fQueryPlus= "\t$";                                     // gopher+, call for all needed data
  99.         }
  100.         
  101.     DGopher::OpenQuery();        
  102. }
  103.  
  104. #if GOOBSOLETE
  105. short DFolderGopher::GopherIt() // override 
  106. {
  107.     ReadAll();
  108.     if (fInfo && fInfoSize>10) 
  109.         return cNewGopherFolder;
  110.     else  
  111.         return cNoCommand;
  112. }
  113.  
  114. #endif
  115.  
  116.  
  117.  
  118. // DTextGopher -----------------------------
  119.  
  120. #ifdef WIN_MSWIN
  121. long    DTextGopher::kMacType = 1234;
  122. long    DTextGopher::kMacSire = 4321;
  123. #else
  124. long    DTextGopher::kMacType = 'TEXT';
  125. long    DTextGopher::kMacSire = 'EDIT';
  126. #endif
  127. char * DTextGopher::kSuffix = ".text";
  128.  
  129. void DTextGopher::InitSignature()     
  130. {
  131.     if (gGopherMap) gGopherMap->GetPreferedFiletype("text/plain", kMacType, kMacSire, kSuffix);     
  132. }
  133.  
  134. void DTextGopher::Initialize()    // override 
  135. {
  136.     //? fType= kTypeFile; 
  137.     fMacType= kMacType; 
  138.     fMacSire= kMacSire; 
  139.     fTransferType= kTransferText; 
  140.     fSaveToDisk= false;
  141.     fLaunch= false;
  142.     fCommand= cNewGopherText;
  143. }
  144.  
  145. DTextGopher::DTextGopher(): DGopher()
  146. {
  147.     Initialize();
  148. }
  149.  
  150. DTextGopher::DTextGopher( DTextGopher* aGopher): DGopher(aGopher)
  151. {
  152.     //Initialize();
  153. }
  154.  
  155. DTextGopher::DTextGopher( char ctype, const char* link):
  156.     DGopher( ctype, link)
  157. {
  158.     Initialize();
  159. }
  160.  
  161.  
  162. DObject* DTextGopher::Clone()
  163. {
  164.     DTextGopher* aGopher= new DTextGopher();
  165.     aGopher->CopyGopher( this);
  166.     return aGopher;
  167. }
  168.  
  169. void DTextGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  170. {
  171.     gGopherIconID= kTextIcon;
  172.     gIconSize= size;
  173.     DrawIconSub( area);
  174. }
  175.  
  176. const char* DTextGopher::GetKindName() 
  177.     return "Text document";
  178. }
  179.  
  180.  
  181. void DTextGopher::OpenQuery()
  182. {
  183.     if (fQueryPlus != NULL)  ;             // if wrapper has set this (for +ASK reply) leave it
  184.     else if (fIsPlus != kGopherPlusYes) fQueryPlus= NULL;
  185.     else fQueryPlus= "\t+"; // gopher+, this form forces server to send data size first
  186.  
  187.     DGopher::OpenQuery();        
  188.     if (fTalker) fTalker->NullTerm(true); //!?
  189.     if (fTransferType == kTransferText 
  190.             && fInfo && fInfoSize>0 && fInfo[fInfoSize] == kLF) 
  191.                 fInfo[fInfoSize--]= 0;  
  192. }
  193.  
  194.  
  195.  
  196. #if GOOBSOLETE
  197. short DTextGopher::GopherIt()
  198. {
  199.     short    command= cNoCommand;
  200.     Boolean tooBig= false;
  201.     Boolean FileIsMade= false;
  202.     long chunksize = kReadMaxbuf1; //Min( FreeMem()/2, kReadMaxbuf1);
  203.     long maxmemtext = kMaxMemory; //FreeMem();
  204.     //maxmemtext = maxmemtext - (maxmemtext / 3);
  205.  
  206.     OpenQuery();        
  207.     
  208.     if (fBytesExpected > 0) tooBig= (fBytesExpected > maxmemtext);
  209.  
  210. #if 1
  211.     if (fInfoHandler)
  212.      while (!EndOfMessage()) {
  213.             ReadAChunk( maxmemtext);
  214.             //(fInfoHandler)(this);
  215.             fInfoHandler->Process();
  216.             }
  217.     else
  218. #endif    
  219.     
  220.     while (!EndOfMessage()) {
  221.         if (tooBig || fSaveToDisk) {
  222.             fThreadState= kThreadReadingToDisk;
  223.             if (tooBig && fTalker) fTalker->ShowMessage("More text than app can display.");
  224.             FileIsMade= ReadToFile( chunksize);
  225.             if (FileIsMade) command= cOpenGopherText;
  226.             else command= cNewGopherText;
  227.             if (fTalker) fTalker->SetEndOfMessage(true);
  228.             }
  229.         else {
  230.             ReadAChunk( maxmemtext);
  231.             //tooBig= (!EndOfMessage());
  232.             if (fTalker) tooBig = (fTalker->NewBytesReceived() == -1);
  233.             command= cNewGopherText;
  234.             }
  235.         } 
  236.     
  237.     FinishRead();
  238.     if (fLaunch) { (void) this->LaunchFile(); command= cNoCommand; }
  239.     CloseQuery();
  240.     
  241.     return command;
  242. }
  243. #endif // GOOBSOLETE
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254. //    DIndexGopher    -----------------
  255.  
  256.             
  257. const short    kGopherSearchID    = 2204;    // dialog window for search query 
  258.                                                                         // do we want this public or private ?
  259.  
  260. class DIndexDialog : public DWindow
  261. {
  262. public:
  263.     static char *gLastQuery;
  264.     DEditText* fQuery;
  265.     
  266.     DIndexDialog( long id, DGopher* itsGoph) :
  267.         DWindow( id, gApplication, fixed, -10, -10, -50, -20, "Gopher Query", kDontFreeOnClose)
  268.     {
  269.         char *kSpacers = "                            "; // 28 spc
  270.         char    buf[255];
  271.         sprintf(buf,"%s?", (char*)itsGoph->GetName());
  272.         DPrompt* pr= new DPrompt(0, this, buf, 0, 0, Nlm_programFont);             
  273.         this->NextSubviewBelowLeft();
  274.         fQuery= new DEditText(0, this, kSpacers, 28); // save last query default???
  275.         fQuery->SetTitle(gLastQuery);
  276.         this->SetEditText(fQuery);
  277.         this->AddOkayCancelButtons(cOKAY,"Send");
  278.     }
  279.             
  280.     char* Result()
  281.     {
  282.         if (fOkay) {
  283.             //return fQuery->GetText();
  284.             long len = fQuery->TextLength();
  285.             if (!len) return NULL;
  286.             char *txt = (char*) MemNew(len+2);
  287.             *txt= '\t'; // precede word w/ tab for gopher
  288.             fQuery->GetTitle( txt+1, len+1);
  289.             if (gLastQuery) MemFree(gLastQuery);
  290.             gLastQuery= StrDup( txt+1);
  291.             return txt;
  292.             }
  293.         else return NULL;
  294.     }
  295.     
  296. };
  297.  
  298. char* DIndexDialog::gLastQuery = NULL;
  299.  
  300.  
  301. Boolean DIndexGopher::PoseQuestion(CharPtr& query)
  302. {
  303.     query= NULL; //?? we create this storage
  304.  
  305.     DIndexDialog* win= new DIndexDialog(0, this);
  306.     if ( win->PoseModally() ) ;
  307.     query= win->Result();
  308.     delete win;  
  309.     return (query != NULL);
  310. }
  311.         
  312. void DIndexGopher::InfoTask() 
  313. {    
  314.     fThreadState= kThreadDoneReading; 
  315. }
  316.  
  317.  
  318. void DIndexGopher::CloseQuery()
  319. {
  320.     DFolderGopher::CloseQuery();
  321.     if (fQuery) fQuery= (char*) MemFree( fQuery);
  322.  
  323. #if 0
  324.     char* kBombBugPatch = "i(Quick bug patch for obscure bomb)\t\t\t0"CRLF;    
  325.  
  326.     
  327.     DGopher* ago= new DGopher();
  328.     ago->SetLink( *fInfo, fInfo);
  329.     char link1[512];
  330.     sprintf( link1, "%c%s\t%s\t%s\t%d\t%c",
  331.         ago->fType, (char*) ago->GetName(), (char*) ago->GetPath(), 
  332.         (char*) ago->GetHost(), ago->fPort, ' ');
  333.     delete ago;
  334.     
  335.     char *next= fInfo;
  336.     next= StrChr(next, kLF);
  337.     if (next) next++;
  338.     
  339.     char *tmp= StrDup(kBombBugPatch);
  340.  
  341.     StrExtendCat( &tmp, link1);
  342.     StrExtendCat( &tmp, next);
  343.     //StrExtendCat( &tmp, fInfo);
  344.     MemFree(fInfo);
  345.     fInfo= tmp;
  346.     fInfoSize= StrLen(fInfo);
  347.  
  348. #endif
  349.  
  350. }
  351.  
  352. void DIndexGopher::OpenQuery()
  353. {
  354.     char*        query;                //?? need to save user query for doc word highlighting 
  355.     gCursor->arrow();
  356.     
  357.     if (fQueryGiven) {
  358.         fQuery= (char*) MemNew( 2 + StrLen(fQueryGiven));
  359.         fQuery[0]= '\t';
  360.         StrCpy(fQuery+1,fQueryGiven);
  361.         //DFolderGopher::OpenQuery(); << no, sends \t+ which leads client to ask for !info, which server can't produce
  362.         DGopher::OpenQuery();
  363.         }
  364.     else if (PoseQuestion(query)) { // this query str is made new for us
  365.         gCursor->watch();
  366.         fQuery= query;
  367.         //DFolderGopher::OpenQuery(); << no, sends \t+ which leads client to ask for !info, which server can't produce
  368.         DGopher::OpenQuery();
  369.         }
  370.     else {
  371.         fBytesExpected= 0;
  372.         fBytesReceived= 0;
  373.         if (fTalker) fTalker->SetEndOfMessage(true);
  374.         fThreadState= kThreadDoneReading;
  375.         //?? what will kill read??
  376.         }
  377. }
  378.         
  379.         
  380. #if GOOBSOLETE
  381. short DIndexGopher::GopherIt() // override 
  382. {
  383.     char*        query;                //?? need to save user query for doc word highlighting 
  384.     short    result= cNoCommand;
  385.     
  386.     result= DFolderGopher::GopherIt();
  387.     return result;
  388. }
  389. #endif// GOOBSOLETE
  390.  
  391.  
  392. void DIndexGopher::Initialize() 
  393. {
  394. }
  395.  
  396. DIndexGopher::DIndexGopher(): DFolderGopher()
  397. {
  398.     Initialize();
  399. }
  400.  
  401. DIndexGopher::DIndexGopher(DIndexGopher* aGopher): DFolderGopher(aGopher)
  402. {
  403.     //Initialize();
  404. }
  405.  
  406. DIndexGopher::DIndexGopher( char ctype, const char* link): DFolderGopher( ctype, link)
  407. {
  408.     Initialize();
  409. }
  410.  
  411. DObject* DIndexGopher::Clone()
  412. {
  413.     DIndexGopher* aGopher= new DIndexGopher();
  414.     aGopher->CopyGopher( this);
  415.     return aGopher;
  416. }
  417.  
  418. void DIndexGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  419. {
  420.     gGopherIconID= kIndexIcon;
  421.     gIconSize= size;
  422.     DrawIconSub( area);
  423. }
  424.  
  425. const char* DIndexGopher::GetKindName() 
  426.     return "Query";
  427. }
  428.  
  429.  
  430.  
  431. #ifdef WIN_MSWIN
  432. long    DBinaryGopher::kMacType = 1235;
  433. long    DBinaryGopher::kMacSire = 3215;
  434. #else
  435. long    DBinaryGopher::kMacType = 'BINA';
  436. long    DBinaryGopher::kMacSire = '    ';
  437. #endif
  438. char * DBinaryGopher::kSuffix = ".binary";
  439.  
  440. void DBinaryGopher::InitSignature()     
  441. {
  442.     if (gGopherMap) gGopherMap->GetPreferedFiletype("file/-", kMacType, kMacSire, kSuffix);     
  443. }
  444.  
  445. void DBinaryGopher::Initialize()    // override 
  446. {
  447.     fMacType= kMacType; //'BINA';  
  448.     fMacSire= kMacSire; //'????';
  449.     fTransferType= kTransferBinary; //text/lines or binary or none ?
  450.     fSaveToDisk= true;
  451.     fLaunch= false;
  452.     fCommand= cNewGopherFile;
  453. }
  454.  
  455.  
  456. DBinaryGopher::DBinaryGopher(): DGopher()
  457. {
  458.     Initialize();
  459. }
  460.  
  461. DBinaryGopher::DBinaryGopher(DBinaryGopher* aGopher): DGopher(aGopher)
  462. {
  463.     //Initialize();
  464. }
  465.  
  466.  
  467. DBinaryGopher::DBinaryGopher( char ctype, const char* link):
  468.     DGopher( ctype, link)
  469. {
  470.     Initialize();
  471. }
  472.  
  473.  
  474. DObject* DBinaryGopher::Clone()
  475. {
  476.     DBinaryGopher* aGopher= new DBinaryGopher();
  477.     aGopher->CopyGopher( this);
  478.     return aGopher;
  479. }
  480.  
  481.  
  482. void DBinaryGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  483. {
  484.     gGopherIconID= kBinaryIcon;
  485.     gIconSize= size;
  486.     DrawIconSub( area);
  487. }
  488.  
  489. const char* DBinaryGopher::GetKindName() 
  490.     return "Binary file";
  491. }
  492.  
  493.  
  494.  
  495.  
  496. void DBinaryGopher::OpenQuery()
  497. {
  498.     if (fQueryPlus != NULL)  ;             // if wrapper has set this (for +ASK reply) leave it
  499.     else if (fIsPlus != kGopherPlusYes) fQueryPlus= NULL;
  500.     else fQueryPlus= "\t+"; // gopher+, this form forces server to send data size first
  501.  
  502.     DGopher::OpenQuery();        
  503. }
  504.  
  505. #if GOOBSOLETE
  506. short DBinaryGopher::GopherIt()
  507. {    
  508.     short    result= cNoCommand;
  509.     Boolean FileIsMade= false;
  510.     long chunksize = kReadMaxbuf1; //Min( FreeMem()/2, kReadMaxbuf1);
  511.  
  512.     OpenQuery();        
  513. #if 1
  514.     if (fInfoHandler)
  515.      while (!EndOfMessage()) {
  516.             ReadAChunk( chunksize);
  517.             //(fInfoHandler)(this);
  518.             fInfoHandler->Process();
  519.             }
  520.     else
  521. #endif    
  522.         FileIsMade= ReadToFile( chunksize);
  523.     if (fLaunch) (void) this->LaunchFile();
  524.     CloseQuery();
  525.     return result;
  526. }
  527. #endif  // GOOBSOLETE
  528.  
  529.  
  530.  
  531.  
  532.  
  533. #ifdef WIN_MSWIN
  534. long    DSoundGopher::kMacType = 4333;
  535. long    DSoundGopher::kMacSire = 3334;
  536. #else
  537. long    DSoundGopher::kMacType = 'snd ';
  538. long    DSoundGopher::kMacSire = '    ';
  539. #endif
  540. char * DSoundGopher::kSuffix = ".sound";
  541.  
  542. void DSoundGopher::InitSignature()     
  543. {
  544.     if (gGopherMap) gGopherMap->GetPreferedFiletype("audio/-", kMacType, kMacSire, kSuffix);     
  545. }
  546.  
  547. void DSoundGopher::Initialize()    // override 
  548. {
  549.     //? fType= kTypeSound; 
  550.     fMacType= kMacType; //'snd ';   
  551.     fMacSire= kMacSire; //'    ';
  552.     fTransferType= kTransferBinary; //text/lines or binary or none ?
  553.     fSaveToDisk= true;
  554.     fLaunch= false; //?? true, but how ?
  555.     fCommand= cNewGopherFile;
  556. }
  557.  
  558. DSoundGopher::DSoundGopher(): DBinaryGopher()
  559. {
  560.     Initialize();
  561. }
  562.  
  563. DSoundGopher::DSoundGopher(DSoundGopher* aGopher): DBinaryGopher(aGopher)
  564. {
  565.     //Initialize();
  566. }
  567.  
  568. DSoundGopher::DSoundGopher( char ctype, const char* link):
  569.     DBinaryGopher( ctype, link)
  570. {
  571.     Initialize();
  572. }
  573.  
  574. DObject* DSoundGopher::Clone()
  575. {
  576.     DSoundGopher* aGopher= new DSoundGopher();
  577.     aGopher->CopyGopher( this);
  578.     return aGopher;
  579. }
  580.  
  581. void DSoundGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  582. {
  583.     gGopherIconID= kSoundIcon;
  584.     gIconSize= size;
  585.     DrawIconSub( area);
  586. }
  587.  
  588. const char* DSoundGopher::GetKindName() 
  589.     return "Sound";
  590. }
  591.  
  592. #if GOOBSOLETE
  593. short DSoundGopher::GopherIt(void) // override 
  594. {
  595.     return DBinaryGopher::GopherIt();
  596. }
  597. #endif  // GOOBSOLETE
  598.  
  599.  
  600.  
  601.  
  602. #ifdef WIN_MSWIN
  603. long    DImageGopher::kMacType = 5555;
  604. long    DImageGopher::kMacSire = 3333;
  605. #else
  606. long    DImageGopher::kMacType = 'GIFf';
  607. long    DImageGopher::kMacSire = 'JVWR';
  608. #endif
  609. char * DImageGopher::kSuffix = ".image";
  610.  
  611. void DImageGopher::InitSignature()     
  612. {
  613.     if (gGopherMap) gGopherMap->GetPreferedFiletype("image/-", kMacType, kMacSire, kSuffix);     
  614. }
  615.  
  616. void DImageGopher::Initialize()    // override 
  617. {
  618.     //? fType= kTypeImage; 
  619.     fMacType= kMacType; //'GIFf';   
  620.     fMacSire= kMacSire; //'Bozo';  
  621.     fTransferType= kTransferBinary; //text/lines or binary or none ?
  622.     fSaveToDisk= true;
  623.     fLaunch= false; 
  624.     fCommand= cNewGopherImage;
  625. }
  626.  
  627. DImageGopher::DImageGopher(): DBinaryGopher()
  628. {
  629.     Initialize();
  630. }
  631.  
  632. DImageGopher::DImageGopher(DImageGopher* aGopher): DBinaryGopher(aGopher)
  633. {
  634.     //Initialize();
  635. }
  636.  
  637. DImageGopher::DImageGopher( char ctype, const char* link):
  638.     DBinaryGopher( ctype, link)
  639. {
  640.     Initialize();
  641. }
  642.  
  643. DObject* DImageGopher::Clone()
  644. {
  645.     DImageGopher* aGopher= new DImageGopher();
  646.     aGopher->CopyGopher( this);
  647.     return aGopher;
  648. }
  649.  
  650. void DImageGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  651. {
  652.     gGopherIconID= kImageIcon;
  653.     gIconSize= size;
  654.     DrawIconSub( area);
  655. }
  656.  
  657. const char* DImageGopher::GetKindName() 
  658.     return "Image";
  659. }
  660.  
  661. #if GOOBSOLETE
  662. short DImageGopher::GopherIt() // override 
  663. {
  664.     return DBinaryGopher::GopherIt();
  665. }
  666. #endif
  667.  
  668.  
  669.  
  670.  
  671.  
  672. #ifdef WIN_MSWIN
  673. long    DMovieGopher::kMacType = 3322;
  674. long    DMovieGopher::kMacSire = 2233;
  675. #else
  676. long    DMovieGopher::kMacType = 'MooV';
  677. long    DMovieGopher::kMacSire = 'TVOD';
  678. #endif
  679. char * DMovieGopher::kSuffix = ".movie";
  680.  
  681. void DMovieGopher::InitSignature()     
  682. {
  683.     if (gGopherMap) gGopherMap->GetPreferedFiletype("movie/-", kMacType, kMacSire, kSuffix);     
  684. }
  685.  
  686. void DMovieGopher::Initialize()    // override 
  687. {
  688.     //? fType= kTypeMovie; 
  689.     fMacType= kMacType; //'MooV';   
  690.     fMacSire= kMacSire; //'TVOD';   
  691.     fTransferType= kTransferBinary; //text/lines or binary or none ?
  692.     fSaveToDisk= true;
  693.     fLaunch= false; 
  694.     fCommand= cNewGopherFile;
  695. }
  696.  
  697. DMovieGopher::DMovieGopher(): DBinaryGopher()
  698. {
  699.     Initialize();
  700. }
  701.  
  702. DMovieGopher::DMovieGopher(DMovieGopher* aGopher): DBinaryGopher(aGopher)
  703. {
  704.     //Initialize();
  705. }
  706.  
  707. DMovieGopher::DMovieGopher( char ctype, const char* link):
  708.     DBinaryGopher( ctype, link)
  709. {
  710.     Initialize();
  711. }
  712.  
  713. DObject* DMovieGopher::Clone()
  714. {
  715.     DMovieGopher* aGopher= new DMovieGopher();
  716.     aGopher->CopyGopher( this);
  717.     return aGopher;
  718. }
  719.  
  720. void DMovieGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  721. {
  722.     gGopherIconID= kMovieIcon;
  723.     gIconSize= size;
  724.     DrawIconSub( area);
  725. }
  726.  
  727. const char* DMovieGopher::GetKindName() 
  728.     return "Movie";
  729. }
  730.  
  731. #if GOOBSOLETE
  732. short DMovieGopher::GopherIt() // override 
  733. {
  734.     return DBinaryGopher::GopherIt();
  735. }
  736. #endif
  737.  
  738.  
  739.  
  740. void DNoteGopher::Initialize()    // override 
  741. {
  742.     //? fType= kTypeNote; 
  743. #ifdef WIN_MSWIN
  744. #else
  745.     fMacType= 'TEXT';
  746.     fMacSire= 'Rich';
  747. #endif
  748.     fTransferType= kTransferText;  
  749.     fSaveToDisk= true;
  750.     fLaunch= false; 
  751.     fCommand= cNoCommand;
  752. }
  753.  
  754. DNoteGopher::DNoteGopher(): DGopher()
  755. {
  756.     Initialize();
  757. }
  758.  
  759. DNoteGopher::DNoteGopher(DNoteGopher* aGopher): DGopher(aGopher)
  760. {
  761.     //Initialize();
  762. }
  763.  
  764. DNoteGopher::DNoteGopher( char ctype, const char* link):
  765.     DGopher( ctype, link)
  766. {
  767.     Initialize();
  768. }
  769.  
  770. DObject* DNoteGopher::Clone()
  771. {
  772.     DNoteGopher* aGopher= new DNoteGopher();
  773.     aGopher->CopyGopher( this);
  774.     return aGopher;
  775. }
  776.  
  777. void DNoteGopher::InfoTask() 
  778. {    
  779.     fThreadState= kThreadDoneReading; 
  780. }
  781.  
  782. void DNoteGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  783. {
  784.     gGopherIconID= kNoteIcon;
  785.     gIconSize= size;
  786.     DrawIconSub( area);
  787. }
  788.  
  789. const char* DNoteGopher::GetKindName() 
  790.     return "Note";
  791. }
  792.  
  793. #if GOOBSOLETE
  794. short DNoteGopher::GopherIt() // override 
  795. {
  796.     return cNoCommand; //DGopher::GopherIt();
  797. }
  798. #endif
  799.  
  800.  
  801.  
  802.  
  803. // DHtmlGopher
  804.  
  805. void DHtmlGopher::Initialize()    // override 
  806. {
  807.     //? fType= kTypeNote; 
  808. #ifdef WIN_MSWIN
  809. #else
  810.     fMacType= 'TEXT';
  811.     fMacSire= 'Rich';
  812. #endif
  813.     fTransferType= kTransferText;  
  814.     fSaveToDisk= false;
  815.     fLaunch= false; 
  816.     fCommand= cNewGopherText;
  817. }
  818.  
  819. DHtmlGopher::DHtmlGopher(): DTextGopher()
  820. {
  821.     Initialize();
  822. }
  823.  
  824. DHtmlGopher::DHtmlGopher(DHtmlGopher* aGopher): DTextGopher(aGopher)
  825. {
  826.     //Initialize();
  827. }
  828.  
  829. DHtmlGopher::DHtmlGopher( char ctype, const char* link):
  830.     DTextGopher( ctype, link)
  831. {
  832.     Initialize();
  833. }
  834.  
  835. DObject* DHtmlGopher::Clone()
  836. {
  837.     DHtmlGopher* aGopher= new DHtmlGopher();
  838.     aGopher->CopyGopher( this);
  839.     return aGopher;
  840. }
  841.  
  842.  
  843. void DHtmlGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  844. {
  845.     gGopherIconID= kHTMLIcon; 
  846.     gIconSize= size;
  847.     DrawIconSub( area);
  848. }
  849.  
  850. const char* DHtmlGopher::GetKindName() 
  851.     return "HTML document";
  852. }
  853.  
  854.  
  855.  
  856.  
  857. void DMailGopher::Initialize()    // override 
  858. {
  859.     //? fType= kTypeNote; 
  860. #ifdef WIN_MSWIN
  861. #else
  862.     fMacType= 'TEXT';
  863.     fMacSire= 'Rich';
  864. #endif
  865.     fTransferType= kTransferText;  
  866.     fSaveToDisk= true;
  867.     fLaunch= false; 
  868.     //fCommand= cNoCommand;
  869.     fCommand= kGopherTask; // this is wrong, but need something for processing
  870. }
  871.  
  872. DMailGopher::DMailGopher(): DGopher()
  873. {
  874.     Initialize();
  875. }
  876.  
  877. DMailGopher::DMailGopher(DMailGopher* aGopher): DGopher(aGopher)
  878. {
  879.     //Initialize();
  880. }
  881.  
  882. DMailGopher::DMailGopher( char ctype, const char* link):
  883.     DGopher( ctype, link)
  884. {
  885.     Initialize();
  886. }
  887.  
  888. void DMailGopher::InfoTask() 
  889. {    
  890.     fThreadState= kThreadDoneReading; 
  891. }
  892.  
  893.  
  894. void DMailGopher::OpenQuery()
  895. {
  896.     char *mailto= (char*) this->GetPath();
  897.     char *wintitle= (char*)this->ShortName(); //"Mail To";
  898.     DSendMailDialog* win= 
  899.         new DSendMailDialog(0, gApplication, -10, -10, -20, -20, wintitle);
  900.     win->InstallTo(win, mailto);
  901.     win->InstallSubject(win, (char*)this->GetName());
  902.     if (fQueryPlus) win->InstallMessage(win, fQueryPlus);// use this handle for mail message?
  903.     win->Open();
  904.     
  905.     fThreadState= kThreadDoneReading;
  906. }
  907.  
  908. DObject* DMailGopher::Clone()
  909. {
  910.     DMailGopher* aGopher= new DMailGopher();
  911.     aGopher->CopyGopher( this);
  912.     return aGopher;
  913. }
  914.  
  915. void DMailGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  916. {
  917.     gGopherIconID= kNoteIcon;
  918.     gIconSize= size;
  919.     DrawIconSub( area);
  920. }
  921.  
  922. const char* DMailGopher::GetKindName() 
  923.     return "Mailto";
  924. }
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931. void DHTTPGopher::Initialize()    // override 
  932. {
  933.     //? fType= kTypeNote; 
  934. #ifdef WIN_MSWIN
  935. #else
  936.     fMacType= 'TEXT';
  937.     fMacSire= 'Rich';
  938. #endif
  939.     fTransferType= kTransferText;  
  940.     fProtocol= kHTTPprot;
  941.     fSaveToDisk= true;
  942.     fLaunch= false; 
  943.     //fCommand= cNoCommand;
  944.     fCommand= kGopherTask; // this is wrong, but need something for processing
  945. }
  946.  
  947. DHTTPGopher::DHTTPGopher(): DGopher()
  948. {
  949.     Initialize();
  950. }
  951.  
  952. DHTTPGopher::DHTTPGopher(DHTTPGopher* aGopher): DGopher(aGopher)
  953. {
  954.     //Initialize();
  955. }
  956.  
  957. DHTTPGopher::DHTTPGopher( char ctype, const char* link):
  958.     DGopher( ctype, link)
  959. {
  960.     Initialize();
  961. }
  962.  
  963. void DHTTPGopher::InfoTask() 
  964. {    
  965.     fThreadState= kThreadDoneReading; 
  966. }
  967.  
  968.  
  969. void DHTTPGopher::OpenQuery()
  970. {
  971.     DGopher::OpenQuery();        
  972.     if (fTalker) fTalker->NullTerm(true); //!?
  973.     if (fTransferType == kTransferText 
  974.             && fInfo && fInfoSize>0 && fInfo[fInfoSize] == kLF) 
  975.                 fInfo[fInfoSize--]= 0;  
  976. }
  977.  
  978. DObject* DHTTPGopher::Clone()
  979. {
  980.     DHTTPGopher* aGopher= new DHTTPGopher();
  981.     aGopher->CopyGopher( this);
  982.     return aGopher;
  983. }
  984.  
  985. void DHTTPGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  986. {
  987.     gGopherIconID= kTextIcon; //kHTTPIcon; // ! want own icon
  988.     gIconSize= size;
  989.     DrawIconSub( area);
  990. }
  991.  
  992. const char* DHTTPGopher::GetKindName() 
  993.     return "HTTP link";
  994. }
  995.  
  996.  
  997.  
  998.  
  999.  
  1000.  
  1001. // DBinhexGopher.cp
  1002. //   class to convert HQX encoded data to Mac file
  1003.  
  1004.  
  1005. void DBinhexGopher::Initialize()    // override 
  1006. {
  1007.     //? fType= kTypeBinhex; 
  1008. #ifdef WIN_MSWIN
  1009. #else
  1010.     fMacType= 'TEXT';
  1011.     fMacSire= 'EDIT';
  1012. #endif
  1013.     fTransferType= kTransferBinary;  //< should be okay for binhex translator 
  1014.     fSaveToDisk= true;
  1015.     fLaunch= false; //true; ??
  1016.     fCommand= cNewGopherFile;
  1017.  
  1018.     fHqxbuf= NULL;
  1019. }
  1020.  
  1021. DBinhexGopher::DBinhexGopher(): DGopher()
  1022. {
  1023.     Initialize();
  1024. }
  1025.  
  1026. DBinhexGopher::DBinhexGopher(DBinhexGopher* aGopher): DGopher(aGopher)
  1027. {
  1028.     //Initialize();
  1029.     fHqxbuf= NULL;
  1030. }
  1031.  
  1032. DBinhexGopher::DBinhexGopher( char ctype, const char* link):
  1033.     DGopher( ctype, link)
  1034. {
  1035.     Initialize();
  1036. }
  1037.  
  1038. DObject* DBinhexGopher::Clone()
  1039. {
  1040.     DBinhexGopher* aGopher= new DBinhexGopher();
  1041.     aGopher->CopyGopher( this);
  1042.     return aGopher;
  1043. }
  1044.  
  1045. void DBinhexGopher::DrawIcon( Nlm_RecT& area, short size)  //override 
  1046. {
  1047.     gGopherIconID= kBinhexIcon;
  1048.     gIconSize= size;
  1049.     DrawIconSub( area);
  1050. }
  1051.  
  1052. const char* DBinhexGopher::GetKindName() 
  1053.     return "Binhex file";
  1054. }
  1055.  
  1056.  
  1057.  
  1058. #ifdef FIX_LATER
  1059.  
  1060. const long kNeedMoreHQXData = -1;
  1061. const long msgMyError = 0x80001234;
  1062.  
  1063.  
  1064. /* from hqxify.c in
  1065.  * mcvert.c - version 1.05 - 10 January, 1990 modified 12 March, 1990 by NP
  1066.  * Written by Doug Moore - Rice University - dougm@rice.edu - April '87
  1067.  */
  1068.  
  1069. //#include "debinhex.h"
  1070. /* debinhex.h -- from mactypes.h of mcvert */
  1071.  
  1072. /* Useful, though not particularly Mac related, values */
  1073. typedef unsigned char byte;     /* one byte, obviously */
  1074. typedef unsigned short word;    /* must be 2 bytes */
  1075. typedef unsigned long ulong;    /* 4 bytes */
  1076. #define CR 0x0d
  1077. #define LF 0x0a
  1078.  
  1079.  
  1080. // mpwc
  1081. #define bcopy(a,b,n)  memcpy(b,a,n)
  1082. #define bzero(p,n)      memset(p, 0, n)     
  1083. #define min(a,b)      (a<b)?a:b
  1084. #define max(a,b)      (a>b)?a:b
  1085.  
  1086.  
  1087. #define NAMELEN 63              /* maximum legal Mac file name length */
  1088. #define BINNAMELEN 68           /* NAMELEN + len(".bin\0") */
  1089.  
  1090. /* Format of a bin file:
  1091. A bin file is composed of 128 byte blocks.  The first block is the
  1092. info_header (see below).  Then comes the data fork, null padded to fill the
  1093. last block.  Then comes the resource fork, padded to fill the last block.  A
  1094. proposal to follow with the text of the Get Info box has not been implemented,
  1095. to the best of my knowledge.  Version, zero1 and zero2 are what the receiving
  1096. program looks at to determine if a MacBinary transfer is being initiated.
  1097. */ 
  1098. typedef struct {     /* info file header (128 bytes). Unfortunately, these
  1099.                         longs don't align to word boundaries */
  1100.             byte version;           /* there is only a version 0 at this time */
  1101.             byte nlen;              /* Length of filename. */
  1102.             byte name[NAMELEN];     /* Filename (only 1st nlen are significant)*/
  1103.             byte type[4];           /* File type. */
  1104.             byte auth[4];           /* File creator. */
  1105.             byte flags;             /* file flags: LkIvBnSyBzByChIt */
  1106.             byte zero1;             /* Locked, Invisible,Bundle, System */
  1107.                                     /* Bozo, Busy, Changed, Init */
  1108.             byte icon_vert[2];      /* Vertical icon position within window */
  1109.             byte icon_horiz[2];     /* Horizontal icon postion in window */
  1110.             byte window_id[2];      /* Window or folder ID. */
  1111.             byte protect;           /* = 1 for protected file, 0 otherwise */
  1112.             byte zero2;
  1113.             byte dlen[4];           /* Data Fork length (bytes) -   most sig.  */
  1114.             byte rlen[4];           /* Resource Fork length         byte first */
  1115.             byte ctim[4];           /* File's creation date. */
  1116.             byte mtim[4];           /* File's "last modified" date. */
  1117.             byte ilen[2];           /* GetInfo message length */
  1118.                         byte flags2;            /* Finder flags, bits 0-7 */
  1119.                         byte unused[14];       
  1120.                         byte packlen[4];        /* length of total files when unpacked */
  1121.                         byte headlen[2];        /* length of secondary header */
  1122.                         byte uploadvers;        /* Version of MacBinary II that the uploading program is written for */
  1123.                         byte readvers;          /* Minimum MacBinary II version needed to read this file */
  1124.                         byte crc[2];            /* CRC of the previous 124 bytes */
  1125.                         byte padding[2];        /* two trailing unused bytes */
  1126.                         } info_header;
  1127.  
  1128. /* The *.info file of a MacTerminal file transfer either has exactly this
  1129. structure or has the protect bit in bit 6 (near the sign bit) of byte zero1.
  1130. The code I have for macbin suggests the difference, but I'm not so sure */
  1131.  
  1132. /* Format of a hqx file:
  1133. It begins with a line that begins "(This file
  1134. and the rest is 64 character lines (except possibly the last, and not
  1135. including newlines) where the first begins and the last ends with a colon.
  1136. The characters between colons should be only from the set in tr86, below,
  1137. each of which corresponds to 6 bits of data.  Once that is translated to
  1138. 8 bit bytes, you have the real data, except that the byte 0x90 may 
  1139. indicate, if the following character is nonzero, that the previous
  1140. byte is to be repeated 1 to 255 times.  The byte 0x90 is represented by
  1141. 0x9000.  The information in the file is the hqx_buf (see below),
  1142. a CRC word, the data fork, a CRC word, the resource fork, and a CRC word.
  1143. There is considerable confusion about the flags.  An official looking document
  1144. unclearly states that the init bit is always clear, as is the following byte.
  1145. The experience of others suggests, however, that this is not the case.
  1146. */
  1147.  
  1148. #define HQXLINELEN 64
  1149. typedef struct {
  1150.             byte version;           /* there is only a version 0 at this time */
  1151.             byte type[4];           /* File type. */
  1152.             byte auth[4];           /* File creator. */
  1153.             byte flags;             /* file flags: LkIvBnSyBzByChIt */
  1154.             byte protect;           /* ?Pr??????, don't know what ? bits mean */
  1155.             byte dlen[4];           /* Data Fork length (bytes) -   most sig.  */
  1156.             byte rlen[4];           /* Resource Fork length         byte first */
  1157.             byte bugblank;             /* to fix obscure sun 3/60 problem
  1158.                                           that always makes sizeof(hqx_header
  1159.                                           even */
  1160.             } hqx_header;
  1161.  
  1162. typedef struct {     /* hqx file header buffer (includes file name) */
  1163.             byte nlen;              /* Length of filename. */
  1164.             byte name[NAMELEN];     /* Filename: only nlen actually appear */
  1165.             hqx_header all_the_rest;/* and all the rest follows immediately */
  1166.             } hqx_buf;
  1167.  
  1168.  
  1169. /* An array useful for CRC calculations that use 0x1021 as the "seed" */
  1170. static unsigned short gMagicCRC[] = {
  1171.     0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
  1172.     0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
  1173.     0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
  1174.     0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
  1175.     0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
  1176.     0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
  1177.     0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
  1178.     0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
  1179.     0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
  1180.     0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
  1181.     0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
  1182.     0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
  1183.     0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
  1184.     0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
  1185.     0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
  1186.     0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
  1187.     0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
  1188.     0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
  1189.     0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,
  1190.     0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,
  1191.     0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,
  1192.     0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,
  1193.     0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,
  1194.     0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,
  1195.     0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,
  1196.     0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,
  1197.     0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
  1198.     0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
  1199.     0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
  1200.     0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
  1201.     0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
  1202.     0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0
  1203.     };
  1204.  
  1205.  
  1206. /* Essentials for Binhex 8to6 run length encoding */
  1207. #define RUNCHAR 0x90
  1208. #define MAXRUN 255
  1209. #define IS_LEGAL <0x40
  1210. #define ISNT_LEGAL >0x3f
  1211. #define DONE 0x7F         /* gTrans68[':'] = DONE, since Binhex terminator is ':' */
  1212. #define SKIP 0x7E         /* gTrans68['\n'|'\r'] = SKIP, i. e. end of line char.  */
  1213. #define FAIL 0x7D         /* character illegal in binhex file */
  1214. #define NULLTERM 0x7C /* end of buffer -- need to read more */
  1215.  
  1216. //static byte tr86[] =
  1217. //        "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr"; 
  1218.         
  1219. static byte gTrans68[] = {
  1220.     NULLTERM, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1221.     FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
  1222.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1223.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1224.     FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
  1225.     0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,
  1226.     0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,
  1227.     0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,
  1228.     0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
  1229.     0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,
  1230.     0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,
  1231.     0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,
  1232.     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,
  1233.     0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,
  1234.     0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,
  1235.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1236.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1237.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1238.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1239.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1240.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1241.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1242.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1243.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1244.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1245.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1246.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1247.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1248.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1249.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1250.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1251.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  1252.     };
  1253.  
  1254.  
  1255. #define READING 0
  1256. #define SKIPPING 1
  1257. #define FIND_START_COLON 2
  1258.  
  1259. #define    CRCERROR 1
  1260. #define READERR -1
  1261. #define BINHEX_KEY    "must be converted with BinHex"
  1262.  
  1263. const long     kHqxMaxChunk = kReadMaxbuf1;
  1264. const long  HQXBUFLEN= kHqxMaxChunk;
  1265.  
  1266. #endif // FIX_LATER
  1267.  
  1268.  
  1269.  
  1270. void DBinhexGopher::hqxFini()
  1271. {
  1272. #ifdef FIX_LATER
  1273.     fHqxbuf= (byte*) MemFree( (Ptr)fHqxbuf);
  1274. #endif // FIX_LATER
  1275. }
  1276.  
  1277. void DBinhexGopher::hqxInit() /* call before each hqx file is processed */
  1278. {
  1279. #ifdef FIX_LATER
  1280.     fDecodeStatus = FIND_START_COLON;
  1281.     fHqxbuf= (byte*) MemGet( HQXBUFLEN+1, true);
  1282.     fBufptr= fBufstart= fHqxbuf+1;
  1283.     fBufend= fBufstart + HQXBUFLEN;
  1284.  
  1285.     //fLine= NewPtrClear(MAXLINE+1);
  1286.     //fLinestart= fLine+1;
  1287.     //fLineend= fLinestart + MAXLINE;
  1288.     //fLineptr = fLinestart;
  1289.     //fLineptr[0] = SKIP;
  1290.     
  1291.     fLinecount= 0; //fInoffset = 0; // need to rename this field
  1292.     
  1293.     fTotalbytes = 0;
  1294.     fSavestate = 0;
  1295.     fSaveRunLength = 0;
  1296.     fGotBinhexKey = false;
  1297.  
  1298.     if (fTalker) fTalker->NullTerm( true);  
  1299.     ReadAChunk( kHqxMaxChunk);    
  1300. #endif     // FIX_LATER
  1301. }
  1302.  
  1303.  
  1304. short DBinhexGopher::fill_hqxbuf()
  1305. {   
  1306. #ifdef FIX_LATER
  1307.     register unsigned long c, nibble;
  1308.     register int         not_in_a_run = true, state68;
  1309.     register byte        *inptr, *outptr, *bp;
  1310.     byte                         *instart, *inend, *outend;
  1311.     Boolean                 okay;
  1312.     SignedByte            savedState;    
  1313.  
  1314.     if (!fInfo) return false; // make sure fInfo has data before this
  1315.     savedState = LockHandleHigh(fInfo);  
  1316.     instart= (byte*) *fInfo;
  1317.     inptr= instart + fLinecount; //fInoffset;
  1318.     inend= instart + GetHandleSize( fInfo) - 1;
  1319.     okay= true; //(instart < inend);
  1320.  
  1321.     while (!fGotBinhexKey && okay) {
  1322.         c = 0;
  1323.         while (inptr < inend  && !(*inptr == ':' && (c == kCR || c == kLF))) 
  1324.              c= *inptr++; 
  1325.  
  1326.         if (inptr >= inend) {
  1327.                 // need to expand fInfo, not replace it
  1328.             HUnlock(fInfo);
  1329.             if (*inend == 0) SetHandleSize(fInfo, GetHandleSize( fInfo) - 1); // drop null
  1330.             ReadAChunk( kHqxMaxChunk); 
  1331.             HLock( fInfo);
  1332.             long temp= inptr - instart;
  1333.             instart= (byte*) *fInfo;
  1334.             inptr= instart + temp;
  1335.             byte* tmp1= instart + GetHandleSize( fInfo) - 1;
  1336.             okay = (tmp1 > inend);
  1337.             inend= tmp1;
  1338.             }
  1339.             
  1340.         else { // found key char
  1341.             char* keyptr= (char*) Max( (long)instart, (long)inptr - 82);
  1342.             keyptr= strstr( keyptr, BINHEX_KEY);
  1343.             inptr++; // skip start colon
  1344.             if (keyptr) {
  1345.                 fGotBinhexKey= true;
  1346.                 for (bp= inptr; bp <= inend; bp++) *bp = gTrans68[*bp]; // translate current inputs
  1347.                 }
  1348.             }         
  1349.         }
  1350.     if (!okay) return false; // ran out of input before found start of valid data
  1351.         
  1352.     fDecodeStatus = READING;
  1353.     outptr= fBufptr= fBufstart;
  1354.     outend= fBufend= fBufstart + HQXBUFLEN;
  1355.     state68 = fSavestate;
  1356.     nibble  = fSaveNibble;
  1357.     if (fSaveRunLength > 0) {
  1358.         c = fSaveRunLength;
  1359.         fSaveRunLength = 0;
  1360.         goto continue_run;
  1361.         }
  1362.  
  1363.     while (okay && outptr < outend) {
  1364.  
  1365. next_char:    
  1366.  
  1367.         if (inptr >= inend) { // (?? || c == NULLTERM)
  1368.             //read & translate data
  1369.             HUnlock(fInfo);
  1370.             SetHandleSize(fInfo, 0); // no need to save old inputs
  1371.             ReadAChunk( kHqxMaxChunk); // sticks null at end of read?!
  1372.             if (!fInfo || GetHandleSize(fInfo)<2) { okay= false;  goto data_end; } //out of data
  1373.             HLock( fInfo);
  1374.             inptr= instart= bp= (byte*) *fInfo;
  1375.             inend= instart + GetHandleSize( fInfo) - 1;
  1376.             //while ((*bp = gTrans68[*bp]) IS_LEGAL) bp++;
  1377.             for (bp= inptr; bp <= inend; bp++) *bp = gTrans68[*bp];
  1378.             }
  1379.  
  1380.       c = *inptr++;
  1381.         
  1382.       if (c ISNT_LEGAL) {
  1383.             if (c == DONE) { //kStartOrEnd
  1384.                 fDecodeStatus = READING; //??
  1385.                 okay= false;
  1386.                 }
  1387.             else if (c == NULLTERM) {
  1388.                 //read & translate chunk
  1389.                 //this should be handled by (inptr >= inend)
  1390.                 }
  1391.             else if (c == SKIP) {
  1392.                 // newline
  1393.                 }
  1394.             }
  1395.             
  1396.         else { // (c IS_LEGAL) 
  1397.             if (fDecodeStatus == READING) {
  1398.                 //nibble c;
  1399.                 //stuff c into buf;
  1400.                 //outptr++;
  1401.                 
  1402.         switch (state68++) {
  1403.         case 0:
  1404.             nibble = c;
  1405.             goto next_char;
  1406.         case 1:
  1407.             nibble = (nibble << 6) | c;
  1408.             c = nibble >> 4;
  1409.             break;
  1410.         case 2:
  1411.             nibble = (nibble << 6) | c;
  1412.             c = (nibble >> 2) & 0xff;
  1413.             break;
  1414.         case 3:
  1415.             c = (nibble << 6) & 0xff | c;
  1416.             state68 = 0;
  1417.             break;
  1418.             }
  1419.                         
  1420.         if (not_in_a_run)
  1421.             if (c != RUNCHAR) *outptr++ = c;
  1422.             else {not_in_a_run = false; goto next_char;}
  1423.         else {
  1424.             if (c--) {
  1425.                 not_in_a_run = outend - outptr;
  1426.                 if (c > not_in_a_run) {
  1427.                     fSaveRunLength = c - not_in_a_run;
  1428.                     c = not_in_a_run;
  1429.                     }
  1430.                 continue_run:
  1431.                 not_in_a_run = outptr[-1];
  1432.                 while (c--) *outptr++ = not_in_a_run;
  1433.                 }
  1434.             else *outptr++ = RUNCHAR;
  1435.             not_in_a_run = true;
  1436.             }
  1437.  
  1438.                 }
  1439.                 
  1440.             else if (fDecodeStatus == SKIPPING) {
  1441.                 //???
  1442.                 }
  1443.             
  1444.             }
  1445.         }    
  1446.         
  1447. data_end:
  1448.     fLinecount = inptr - instart; //fInoffset  // save offset from start of fInfo of our move to fHqxbuf
  1449.     if (outptr < outend) fBufend= outptr;
  1450.     fTotalbytes += fBufend - fBufptr; // don't need, dups fBytesread
  1451.     fBufstart[-1] = outptr[-1]; //?? what is this, saving some data b/n calls?
  1452.     fSavestate = state68;
  1453.     fSaveNibble = nibble;
  1454.     HSetState( fInfo, savedState);
  1455.     return (fBufptr < fBufend);
  1456. #endif // FIX_LATER
  1457.     return 0;
  1458. }
  1459.  
  1460.  
  1461. long DBinhexGopher::check_hqx_crc()
  1462. {   
  1463. #ifdef FIX_LATER
  1464.         word read_crc;
  1465.         
  1466.     if (fBufptr >= fBufend) { if (fill_hqxbuf() == false) return READERR;  }
  1467.     read_crc  = *fBufptr++ << 8;
  1468.     if (fBufptr >= fBufend) { if (fill_hqxbuf() == false) return READERR;  }
  1469.     read_crc |= *fBufptr++;
  1470.         return read_crc;
  1471. #endif // FIX_LATER
  1472.     return 0;
  1473. }
  1474.  
  1475. /* This routine reads the header of a hqxed file and appropriately twiddles it,
  1476.     determines if it has CRC problems & returns needed Mac file info */
  1477.  
  1478. short DBinhexGopher::hqx2FinderInfo( char *binfname, long *fauth, long *ftype, 
  1479.                                         unsigned long *hqx_datalen, unsigned long  *hqx_rsrclen) 
  1480. {   
  1481. #ifdef FIX_LATER
  1482.         register byte *hqx_ptr, *hqx_end;
  1483.     register ulong calc_crc;
  1484.         word                hqx_crc;
  1485.         int                    len;
  1486.     hqx_buf         *hqx_block;
  1487.     hqx_header     *hqx;
  1488.  
  1489.     /* read the hqx header, assuming that I won't exhaust hqxbuf in so doing */
  1490.         if (fill_hqxbuf() == false) return READERR;
  1491.         
  1492.     hqx_block = (hqx_buf *) fBufptr;
  1493.       hqx = (hqx_header *) (hqx_block->name + hqx_block->nlen); 
  1494.     hqx_ptr = fBufptr;
  1495.     hqx_end = (byte *) hqx + sizeof(hqx_header) - 1;
  1496.     calc_crc = 0;
  1497.     while (hqx_ptr < hqx_end)
  1498.         calc_crc = (((calc_crc&0xff) << 8) | *hqx_ptr++) ^ gMagicCRC[calc_crc >> 8];
  1499.     calc_crc = ((calc_crc&0xff) << 8) ^ gMagicCRC[calc_crc >> 8];
  1500.     calc_crc = ((calc_crc&0xff) << 8) ^ gMagicCRC[calc_crc >> 8];
  1501.     fBufptr = hqx_ptr;
  1502.  
  1503.         len= min( BINNAMELEN-1, hqx_block->nlen);
  1504.     strncpy( binfname, (char*)hqx_block->name, len);  
  1505.         binfname[len]= 0;
  1506.         bcopy( hqx->auth, fauth, 4);
  1507.         bcopy( hqx->type, ftype, 4);
  1508.     bcopy( hqx->dlen, hqx_datalen, 4);         
  1509.     bcopy( hqx->rlen, hqx_rsrclen, 4);         
  1510.  
  1511.         hqx_crc= check_hqx_crc();
  1512.         if (hqx_crc == (word) calc_crc) return 0;
  1513.         else return CRCERROR;
  1514. #endif    // FIX_LATER
  1515.     return 0;
  1516. }
  1517.  
  1518.  
  1519. /* This routine copies bytes from the decoded input stream to the output. */
  1520.         
  1521. short DBinhexGopher::hqx2fork( short fileref, unsigned long nbytes) 
  1522. {   
  1523. #ifdef FIX_LATER
  1524.         register byte *c;
  1525.     register ulong calc_crc;
  1526.     register ulong c_length;
  1527.         word    hqx_crc;
  1528.         long    buflen;
  1529.  
  1530.     calc_crc = 0;
  1531.     for (;;) {
  1532.         c = fBufptr;
  1533.         buflen = c_length = (c + nbytes > fBufend) ? fBufend - c : nbytes;
  1534.         nbytes -= c_length;
  1535.                 (void) FSWrite( fileref, &buflen, c); 
  1536.                 
  1537.         while (c_length--)
  1538.             calc_crc = (((calc_crc&0xff) << 8) | *c++) ^ gMagicCRC[calc_crc >> 8];
  1539.         if (!nbytes) break;
  1540.                 if (fill_hqxbuf() == false) return READERR;
  1541.         }
  1542.     fBufptr = c;
  1543.     calc_crc = ((calc_crc&0xff) << 8) ^ gMagicCRC[calc_crc >> 8];
  1544.     calc_crc = ((calc_crc&0xff) << 8) ^ gMagicCRC[calc_crc >> 8];
  1545.  
  1546.         hqx_crc= check_hqx_crc();
  1547.     if (hqx_crc == (word) calc_crc) return 0;
  1548.         else return CRCERROR;
  1549. #endif    // FIX_LATER
  1550.     return 0;
  1551. }
  1552.  
  1553.  
  1554.  
  1555. #if GOOBSOLETE
  1556. short DBinhexGopher::GopherIt() // override 
  1557. {    
  1558. #ifdef FIX_LATER
  1559.     short        err,i, fileRef, volRefnum;
  1560.     unsigned long        hqxdatalen, hqxrsrclen;
  1561.     long    fileAuth, fileType;
  1562.     CStr255    fileName;
  1563.     FailInfo    fi;
  1564.     SFReply    reply;
  1565.     Boolean FileIsMade= false;
  1566.  
  1567.     //short saveIsPlus = fIsPlus;
  1568.     //fIsPlus= kGopherPlusNo; // god damn stupid ass bug what the fuck is going on here
  1569.     
  1570.     if (fQueryPlus != NULL)  ;             // if wrapper has set this (for +ASK reply) leave it
  1571.     else if (fIsPlus != kGopherPlusYes) fQueryPlus= NULL;
  1572.     else fQueryPlus= "\t+"; // gopher+, this form forces server to send data size first
  1573.     
  1574.     if (fi.Try()) {
  1575.         OpenQuery();        
  1576.  
  1577.         //if (fTalker->CharsAvailable() == 0) 
  1578.         //    fTalker->ShowMessage("TCP connection timed out");  
  1579.         //else 
  1580.         {
  1581.             if (fTalker) fTalker->ShowMessage("Gopher is digging for data");
  1582.             fileName[1]= 0;
  1583.             
  1584.             hqxInit(); 
  1585.             err= hqx2FinderInfo( (char*)&fileName[1], &fileAuth, &fileType, 
  1586.                                                             &hqxdatalen, &hqxrsrclen);    
  1587.             for (i= 1;  (i<80) && (fileName[i]!=0); i++) ;
  1588.             fileName[0]= i-1;
  1589.         
  1590.             if (fTalker) fTalker->ShowMessage( "Found Binhex file "+fileName);
  1591.             FailOSErr( err); //?
  1592.     
  1593.             // file put dialog: where to save, or cancel...
  1594.             if (gUseDigFolder || !BringAppFrontmost( 0)) {
  1595.                 memcpy(reply.fName, (unsigned char*)fileName, 1+fileName[0]); //reply.fName= fileName;
  1596.                 reply.good= true;  
  1597.                 err= OpenWD( gDigVol, gDigDirID, 0, &reply.vRefNum);
  1598.                 }        
  1599.             else {
  1600.                 CPoint        where;
  1601.                 CenterSFPut( where);
  1602.                 SFPutFile( where,  CStr31("Save fetched file as:"), fileName, NULL, &reply);
  1603.                 gApplication->UpdateAllWindows();
  1604.                 }
  1605.             
  1606.             if (reply.good) {
  1607.                 fileName = reply.fName;
  1608.                 volRefnum = reply.vRefNum;
  1609.                 (void) FSDelete( fileName, volRefnum) ;
  1610.                 FailOSErr( Create( fileName, volRefnum, fileAuth, fileType));
  1611.                 FileIsMade= true;
  1612.                 
  1613.                 if (hqxdatalen>0) {        // data fork
  1614.                     FailOSErr( FSOpen( fileName, volRefnum, &fileRef));
  1615.                     if (fTalker) fTalker->ShowMessage("Reading data fork");
  1616.                     err= hqx2fork( fileRef, hqxdatalen);
  1617.                     (void) FSClose( fileRef);
  1618.                     FailOSErr( err);
  1619.                     }
  1620.                 
  1621.                 if (hqxrsrclen>0) {
  1622.                     FailOSErr( OpenRF( fileName, volRefnum, &fileRef));
  1623.                     if (fTalker) fTalker->ShowMessage("Reading rsrc fork");
  1624.                     err= hqx2fork( fileRef, hqxrsrclen);
  1625.                     (void) FSClose( fileRef);
  1626.                     if (hqxrsrclen > 0) FailOSErr( err); 
  1627.                     }
  1628.                 
  1629.                 // AppFile *pFile = new Appfile;
  1630.                 AppFile    theFile;
  1631.                 DisposeIfHandle( fAppFile);
  1632.                 FailNIL(fAppFile = NewHandle(sizeof(AppFile)));
  1633.                 theFile.vRefNum= volRefnum;  
  1634.                 theFile.fType= fileType;
  1635.                 //theFile.fName= fileName;
  1636.                 memcpy( theFile.fName, &fileName[0], 1+fileName[0]);
  1637.                 memcpy( *fAppFile, &theFile, sizeof(AppFile));
  1638.  
  1639.                 if (fLaunch) (void) this->LaunchFile();
  1640.                 }
  1641.             }
  1642.  
  1643.         hqxFini(); 
  1644.         fi.Success();
  1645.         CloseQuery();
  1646.         }
  1647.     else { // fail
  1648.         hqxFini(); 
  1649.         CloseQuery();
  1650.         if (FileIsMade) (void) FSDelete( fileName, volRefnum);
  1651.         fi.ReSignal();    
  1652.         }
  1653.  
  1654.     //fIsPlus=     saveIsPlus;
  1655. #endif    // FIX_LATER
  1656.     return cNoCommand;
  1657. }
  1658. #endif
  1659.  
  1660.  
  1661.  
  1662.  
  1663.  
  1664.  
  1665. const short kGopherOkayID    = 2206;    // dialog window for messages 
  1666.  
  1667.  
  1668. void DTelnetGopher::Initialize()    // override 
  1669. {
  1670.     //? fType= kTypeTelnet; 
  1671. #ifdef WIN_MSWIN
  1672. #else
  1673.     fMacType= 'CONF';
  1674.     fMacSire= 'NCSA';
  1675. #endif
  1676.     fTransferType= kTransferText; //text/lines or binary or none ?
  1677.     fSaveToDisk= true;
  1678.     fLaunch= true;
  1679.     fCommand= cNewGopherFile;
  1680. }
  1681.  
  1682. DTelnetGopher::DTelnetGopher(): DGopher()
  1683. {
  1684.     Initialize();
  1685. }
  1686.  
  1687. DTelnetGopher::DTelnetGopher(DTelnetGopher* aGopher): DGopher(aGopher)
  1688. {
  1689.     //Initialize();
  1690. }
  1691.  
  1692. DTelnetGopher::DTelnetGopher( char ctype, const char* link):
  1693.     DGopher( ctype, link)
  1694. {
  1695.     Initialize();
  1696. }
  1697.  
  1698. DObject* DTelnetGopher::Clone()
  1699. {
  1700.     DTelnetGopher* aGopher= new DTelnetGopher();
  1701.     aGopher->CopyGopher( this);
  1702.     return aGopher;
  1703. }
  1704.  
  1705. void DTelnetGopher::InfoTask() 
  1706. {    
  1707.     fThreadState= kThreadDoneReading; 
  1708. }
  1709.  
  1710.  
  1711. void DTelnetGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  1712. {
  1713.     gGopherIconID= kTelnetIcon;
  1714.     gIconSize= size;
  1715.     DrawIconSub( area);
  1716. }
  1717.  
  1718. const char* DTelnetGopher::GetKindName() 
  1719.     return "Telnet session";
  1720. }
  1721.  
  1722. void DTelnetGopher::promptUser(char* msg1, char* msg2)
  1723. {
  1724. #ifdef FIX_LATER
  1725.     TWindow *aWind = (TWindow *)gViewServer->NewTemplateWindow(kGopherOkayID, NULL);
  1726.     FailNIL( aWind);          
  1727.     TStaticText    *aTitle = (TStaticText*) aWind->FindSubView('msg1');
  1728.     if (aTitle!=NULL) aTitle->SetText( msg1, kDontRedraw);
  1729.     aTitle = (TStaticText*) aWind->FindSubView('msg2');
  1730.     if (aTitle!=NULL) aTitle->SetText( msg2, kDontRedraw);
  1731.     //TDialogView    *aDlog = (TDialogView*) aWind->FindSubView('DLOG');
  1732.     aWind->SetModality( true); //PoseModally will fail !!
  1733.     IDType dismisser = aWind->PoseModally();
  1734.     //if (dismisser == 'OKAY') ;
  1735.     aWind->CloseAndFree(); 
  1736.     gApplication->UpdateAllWindows();
  1737. #endif    // FIX_LATER
  1738. }
  1739.  
  1740.  
  1741. #if GOOBSOLETE
  1742. short DTelnetGopher::GopherIt() // override 
  1743. /*---- 
  1744. Example Telnet gopher links:
  1745. Name=CUline, University of Colorado,Boulder
  1746. Type=8
  1747. Port=852
  1748. Path=
  1749. Host=culine.Colorado.EDU
  1750.  
  1751. Name=Columbia University
  1752. Type=8
  1753. Port=0
  1754. Path=calendar  << account name to log on as ...
  1755. Host=cal.cc.columbia.edu
  1756. ------*/
  1757. {
  1758. #ifdef FIX_LATER
  1759.     short            i, fileRef, vRefNum;
  1760.     long            dirID;
  1761.     CPoint        where;
  1762.     SFReply        reply;
  1763.     Boolean        okay, hasSystem7;
  1764.     CStr255        msg1, msg2;
  1765. #define          fileName    msg1
  1766.     CStr255     myName= this->GetName();
  1767.     CStr255     myHost= this->GetHost();
  1768.     
  1769.     fileName= myName;  
  1770.     if (fileName.Length() > 31) fileName[0]= 31;
  1771.     for (i= 1; i<= fileName.Length(); i++) if (fileName[i] == ':') fileName[i]= '-';
  1772.     dirID= 0;
  1773.     vRefNum= 0;
  1774.     okay= false;
  1775.     
  1776.     fThreadState= kThreadDoneReading; // this method doesn't read tcp directly
  1777.     
  1778.     if (gUseDigFolder) {
  1779.         vRefNum= gDigVol;
  1780.         dirID= gDigDirID;
  1781.         okay= true;  
  1782.         }
  1783.     /*****        
  1784.     else if (GestaltFlag( gestaltFindFolderAttr, gestaltFindFolderPresent)) {
  1785.         //! can't use kTemporaryFolderType == app can't find files there
  1786.         okay= noErr == FindFolder(kOnSystemDisk,kPreferencesFolderType, 
  1787.                                                                     kCreateFolder,vRefNum,dirID);
  1788.         }
  1789.     *****/
  1790.     
  1791.     if (!okay) {
  1792.         if (!BringAppFrontmost( 0)) {
  1793.             okay= true;
  1794.             vRefNum= gDigVol;
  1795.             dirID= gDigDirID;
  1796.             }        
  1797.         else {
  1798.             CenterSFPut( where);
  1799.             SFPutFile( where, CStr31("Save Telnet session as:"), fileName, NULL, &reply);
  1800.             gApplication->UpdateAllWindows();
  1801.             if (reply.good) {
  1802.                 memcpy((unsigned char*)fileName, reply.fName, 1+reply.fName[0]); //fileName = reply.fName;
  1803.                 vRefNum  = reply.vRefNum;
  1804.                 okay= true;
  1805.                 }
  1806.             }
  1807.         }
  1808.     
  1809.     if (okay) {
  1810.         unsigned int  bufmax = 300 + myName.Length() + myHost.Length();
  1811.         char* buf= (char*) malloc( bufmax);
  1812.         char* cp= buf;
  1813.         sprintf( cp, "name=\"%s\"\n", (char*)myName);  cp += strlen(cp);
  1814.         sprintf( cp, "host=\"%s", (char*)myHost); cp += strlen(cp);
  1815.         if (fPort != 0) { sprintf( cp, " %d", fPort); cp += strlen(cp);}
  1816.         sprintf( cp, "\"\n\0"); cp += strlen(cp);
  1817.         long buflen= strlen( buf);
  1818.         
  1819.         if (0 != HDelete( vRefNum, dirID, fileName)) ;
  1820.         FailOSErr( HCreate( vRefNum, dirID, fileName, fMacSire, fMacType));
  1821.         FailOSErr( HOpen( vRefNum, dirID, fileName, fsWrPerm, &fileRef));
  1822.         FailOSErr( FSWrite( fileRef, &buflen, buf)); 
  1823.         FailOSErr( FSClose( fileRef));
  1824.         free( buf);
  1825.         
  1826.         if (fLaunch && gHasAppleEvents) 
  1827.             hasSystem7= (noErr == LaunchFileThruFinder(vRefNum, dirID, fileName));
  1828.         else
  1829.             hasSystem7= false;
  1830.             
  1831.         if (hasSystem7) msg1= "";
  1832.         else msg1= "To use, launch the telnet session file '" + fileName + "'";
  1833.         //if ( *(*fLink+fIpath)  == 0) msg2= "";
  1834.         if (this->GetPath().Length() == 0) msg2= "";
  1835.         else msg2= "At the telnet login/username prompt, log on as '" 
  1836.                                 + this->GetPath() + CStr31("'");
  1837.         if (!msg1.IsEmpty() || !msg2.IsEmpty()) promptUser(msg1, msg2);
  1838.  
  1839.         //delete temp file...can we do it yet? must be sure finder has launched...
  1840.         //- if (hasSystem7) if (0!=HDelete( vRefNum, dirID, fileName)) ; 
  1841.         // what we really need is a list of garbage/temp files to delete on quitting
  1842.         //    program... include childApp temp files
  1843.         }
  1844.         
  1845.     //SetString( gGopherTitle, myName); 
  1846.     //gGopherData= NULL;
  1847. #endif    // FIX_LATER
  1848.  
  1849.     return cNoCommand;
  1850. }
  1851. #endif // GOOBSOLETE
  1852.  
  1853.  
  1854.  
  1855.  
  1856.  
  1857.  
  1858. #ifdef FIX_LATER
  1859. const short kGopherPhoneID    = 2207;    // dialog window for search query 
  1860.  
  1861. void CCSOPhoneBookGopher::addToInfo( char *cp, short len)
  1862. {
  1863.     Handle h= fInfo;
  1864.     if (h==NULL) FailOSErr( PtrToHand( cp, &h, len));
  1865.     else FailOSErr( PtrAndHand( cp, h, len));
  1866.     if ( cp[len-1] != chRtn ) FailOSErr( PtrAndHand( &chRtn, h, 1));
  1867.     fInfo= h;
  1868. }
  1869.  
  1870.  
  1871.  
  1872. void CCSOPhoneBookGopher::ReadALine() 
  1873. {
  1874.         CStr255        aStr; 
  1875.         char        **data;
  1876.  
  1877.     if (fTalker && fTalker->ReadALine( NULL, data)) {
  1878.         switch (**data) {
  1879.             case '2': if (fTalker) fTalker->SetEndOfMessage(true); break;
  1880.             case '3':
  1881.             case '4':
  1882.             case '5':
  1883.             case '6':
  1884.             case '7':
  1885.             case '8':
  1886.             case '9':  
  1887.                     fTalker->SetEndOfMessage(true);
  1888.                     addToInfo( (*fLink+fIpath), (short)strlen(*fLink+fIpath));
  1889.                     addToInfo( *data + 4, (short) GetHandleSize( data)-4);
  1890.                     break;
  1891.             case '-':  
  1892.                     if (fTalker) fTalker->SetEndOfMessage(false);
  1893.                     addToInfo( *data+7, (short) GetHandleSize( data)-7);
  1894.                     break;
  1895.             }
  1896.         }
  1897. }
  1898.  
  1899.  
  1900. void CCSOPhoneBookGopher::ReadAChunk( long maxchunk) // override  
  1901. {
  1902.     Boolean tooBig;
  1903.     //!! need to read by lines to parse CSO, ? use Inherited (RecvChunk) at all ?
  1904.     do {
  1905.         ReadALine();
  1906.         if (fInfo == NULL) tooBig= false;
  1907.         else tooBig= (GetHandleSize( fInfo) >= maxchunk);
  1908.     } while (!(tooBig || EndOfMessage())); 
  1909. }
  1910.  
  1911.  
  1912. void CCSOPhoneBookGopher::addQuery( long qname, CStr255& query, TWindow* aWind)
  1913. {
  1914.     const short    kOperContains = 1;
  1915.     const short    kOperStarts    = 2;
  1916.     const short    kOperEquals    = 3;
  1917.     CStr255        aStr, bStr;
  1918.  
  1919.     TCluster    *aClus = (TCluster*) aWind->FindSubView(qname);
  1920.     if (aClus!=NULL) {
  1921.         TEditText    *aValue = (TEditText*) aClus->FindSubView('TEXT');
  1922.         aValue->GetText( aStr);
  1923.         if (!aStr.IsEmpty()) {
  1924.             TPopup *aTitle = (TPopup*) aClus->FindSubView('NAME');
  1925.             aTitle->GetItemText( aTitle->GetCurrentItem(), bStr);
  1926.             query += " " + bStr + "=";
  1927.             TPopup *aOper= (TPopup*) aClus->FindSubView('OPER');
  1928.             switch (aOper->GetCurrentItem()) {
  1929.                 case kOperContains: query += "\"*" + aStr + "*\""; break;
  1930.                 case kOperStarts:        query += "\""  + aStr + "*\""; break;
  1931.                 case kOperEquals:        query += "\""  + aStr + "\""; break;
  1932.                 }
  1933.             }
  1934.         }
  1935. }
  1936.  
  1937. Boolean CCSOPhoneBookGopher::queryUser( CStr255& query)
  1938. {
  1939.     CStr255        aStr;
  1940.     Boolean        result= false;
  1941.     
  1942.     TWindow* aWind = (TWindow *)gViewServer->NewTemplateWindow(kGopherPhoneID, NULL);
  1943.     FailNIL( aWind);          
  1944.     //TDialogView    *aDlog = (TDialogView*) aWind->FindSubView('DLOG');
  1945.     aWind->SetModality( true); //PoseModally will fail !!
  1946.     IDType dismisser = aWind->PoseModally();
  1947.     if (dismisser == 'OKAY') {
  1948.         TCheckBox    *aAnd = (TCheckBox*) aWind->FindSubView('cAND');
  1949.         query= "";
  1950.         addQuery('cNM1', query, aWind);
  1951.         if (aAnd->IsOn()) addQuery('cNM2',query, aWind);
  1952.         if (!query.IsEmpty()) {
  1953.             query.Insert("query ", 1);
  1954.             //?? add 'quit' command to close up CSO ??
  1955.             aStr= "12quit"; 
  1956.             aStr[1]= chRtn;
  1957.             aStr[2]= chLineFeed;
  1958.             query= query + aStr;
  1959.             result= true;
  1960.             }            
  1961.         else
  1962.             result= false;
  1963.         }        
  1964.     else
  1965.         result= false;
  1966.     aWind->CloseAndFree(); 
  1967.     gApplication->UpdateAllWindows();
  1968.     return result;
  1969. }
  1970.  
  1971.  
  1972.  
  1973. #if GOOBSOLETE
  1974. short CCSOPhoneBookGopher::GopherIt() // override 
  1975. /********
  1976. example gopher entries for CSO:
  1977. Name=University of Illinois Urbana-Champaign
  1978. Type=2
  1979. Port=105
  1980. Path=
  1981. Host=ns.uiuc.edu
  1982.  
  1983. Simpe gopher CSO dialog:
  1984.  
  1985.   1. Name    :
  1986.   2. Phone   :
  1987.   3. E-Mail  :
  1988.   4. Address :
  1989.  
  1990.     Press 1-4 to change a field, Return to accept fields and continue
  1991. ***********/
  1992. {
  1993.     CStr255     query;             
  1994.     CommandNumber    result= cNoCommand;
  1995.     
  1996.      if (queryUser(query)) {
  1997.         long len = query.Length() + 2;
  1998.         char* queryptr= NewPtr(len);
  1999.         FailNIL(queryptr);
  2000.         strcpy( queryptr, "\t");
  2001.         strcat( queryptr, query);
  2002.         
  2003.         fQuery= queryptr; //(char*) &query[1];    
  2004.         result= DTextGopher::GopherIt(); //Handle as TextGopher 
  2005.         DisposePtr(queryptr);
  2006.         }
  2007.     return result;
  2008. }
  2009. #endif // GOOBSOLETE
  2010.  
  2011.  
  2012. void CCSOPhoneBookGopher::Initialize()    // override 
  2013. {
  2014.     fMacType= 'TEXT';  
  2015.     fMacSire= 'EDIT';
  2016.     fTransferType= kTransferText; //text/lines or binary or none ?
  2017.     fSaveToDisk= false;
  2018.     fLaunch= false;
  2019.     fCommand= cNewGopherFile;
  2020. }
  2021.  
  2022. CCSOPhoneBookGopher::CCSOPhoneBookGopher(): DTextGopher()
  2023. {
  2024.     Initialize();
  2025. }
  2026.  
  2027. CCSOPhoneBookGopher::CCSOPhoneBookGopher(CCSOPhoneBookGopher* aGopher): DTextGopher(aGopher)
  2028. {
  2029.     //Initialize();
  2030. }
  2031.  
  2032. CCSOPhoneBookGopher::CCSOPhoneBookGopher( char ctype, const char* link): DTextGopher( ctype, link)
  2033. {
  2034.     Initialize();
  2035. }
  2036.  
  2037. void CCSOPhoneBookGopher::InfoTask() 
  2038. {    
  2039.     fThreadState= kThreadDoneReading; 
  2040. }
  2041.  
  2042. DObject* CCSOPhoneBookGopher::Clone()
  2043. {
  2044.     CCSOPhoneBookGopher* aGopher= new CCSOPhoneBookGopher();
  2045.     aGopher->CopyGopher( this);
  2046.     return aGopher;
  2047. }
  2048.  
  2049. void CCSOPhoneBookGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  2050. {
  2051.     gGopherIconID= kPhonebookIcon;
  2052.     gIconSize= size;
  2053.     DrawIconSub( area);
  2054. }
  2055.  
  2056. const char* CCSOPhoneBookGopher::GetKindName() 
  2057.     return "CSO Phonebook";
  2058. }
  2059.  
  2060. #endif    // FIX_LATER
  2061.  
  2062.  
  2063.  
  2064.  
  2065. #ifdef FIX_LATER
  2066.     
  2067. Boolean CWhoisPhoneBookGopher::PoseQuestion(CStr255& query) //from DIndexGopher
  2068. {
  2069.     TWindow    *aWind = (TWindow *)gViewServer->NewTemplateWindow(kGopherSearchID, NULL);
  2070.     FailNIL( aWind);          
  2071.     TStaticText    *aTitle = (TStaticText*) aWind->FindSubView('TITL');
  2072.     if (aTitle && fLink)     aTitle->SetText( this->GetName() + CStr31("?"), kRedraw);
  2073.     TEditText    *aFindString = (TEditText*) aWind->FindSubView('QEST');
  2074.     //TDialogView    *aDlog = (TDialogView*) aWind->FindSubView('DLOG');
  2075.     aWind->SetModality( true); //PoseModally will fail !!
  2076.     IDType dismisser = aWind->PoseModally();
  2077.     if (dismisser == 'OKAY') {
  2078.         aFindString->GetText( query);  
  2079.         }        
  2080.     aWind->CloseAndFree(); 
  2081.     gApplication->UpdateAllWindows();
  2082.     return  (dismisser == 'OKAY');
  2083. }
  2084.  
  2085.  
  2086. #if GOOBSOLETE
  2087. short CWhoisPhoneBookGopher::GopherIt() // override 
  2088. {
  2089.     CStr255     query;    
  2090.     CommandNumber    result= cNoCommand;
  2091.     
  2092.     if (PoseQuestion(query)) { 
  2093.         long len = query.Length() + 2;
  2094.         char* queryptr= NewPtr(len);
  2095.         FailNIL(queryptr);
  2096.         strcpy( queryptr, "\t");
  2097.         strcat( queryptr, query);
  2098.         
  2099.         fQuery= queryptr;  
  2100.         result= DTextGopher::GopherIt(); //Handle as TextGopher 
  2101.         DisposePtr( queryptr);
  2102.         }
  2103.     return result;
  2104. }
  2105. #endif // GOOBSOLETE
  2106.  
  2107. void CWhoisPhoneBookGopher::Initialize()    // override 
  2108. {
  2109.     fMacType= 'TEXT';  
  2110.     fMacSire= 'EDIT';
  2111.     fTransferType= kTransferText; //text/lines or binary or none ?
  2112.     fSaveToDisk= false;
  2113.     fLaunch= false;
  2114.     fCommand= cNewGopherFile;
  2115. }
  2116.  
  2117. CWhoisPhoneBookGopher::CWhoisPhoneBookGopher(): DTextGopher()
  2118. {
  2119.     Initialize();
  2120. }
  2121.  
  2122. CWhoisPhoneBookGopher::CWhoisPhoneBookGopher(CWhoisPhoneBookGopher* aGopher): DTextGopher(aGopher)
  2123. {
  2124.     //Initialize();
  2125. }
  2126.  
  2127. CWhoisPhoneBookGopher::CWhoisPhoneBookGopher( char ctype, const char* link): DTextGopher( ctype, link)
  2128. {
  2129.     Initialize();
  2130. }
  2131.  
  2132. DObject* CWhoisPhoneBookGopher::Clone()
  2133. {
  2134.     CWhoisPhoneBookGopher* aGopher= new CWhoisPhoneBookGopher();
  2135.     aGopher->CopyGopher( this);
  2136.     return aGopher;
  2137. }
  2138.  
  2139. void CWhoisPhoneBookGopher::InfoTask() 
  2140. {    
  2141.     fThreadState= kThreadDoneReading; 
  2142. }
  2143.  
  2144. void CWhoisPhoneBookGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  2145. {
  2146.     gGopherIconID= kWhoisPhonebookIcon;
  2147.     gIconSize= size;
  2148.     DrawIconSub( area);
  2149. }
  2150.  
  2151. const char* CWhoisPhoneBookGopher::GetKindName() 
  2152.     return "Whois Phonebook";
  2153. }
  2154.  
  2155. #endif    // FIX_LATER
  2156.  
  2157.  
  2158.  
  2159.  
  2160.  
  2161. #ifdef FIX_LATER
  2162.  
  2163. void CUuencodeGopher::Initialize()    // override 
  2164. {
  2165.     //? fType= kTypeUuencode; 
  2166.     fMacType= 'TEXT';  
  2167.     fMacSire= 'EDIT';
  2168.     fTransferType= kTransferText; //text/lines or binary or none ?
  2169.     fSaveToDisk= false;
  2170.     fLaunch= false;
  2171.     fCommand= cNewGopherFile;
  2172. }
  2173.  
  2174. CUuencodeGopher::CUuencodeGopher(): DTextGopher()
  2175. {
  2176.     Initialize();
  2177. }
  2178.  
  2179. CUuencodeGopher::CUuencodeGopher(CUuencodeGopher* aGopher): DTextGopher(aGopher)
  2180. {
  2181.     //Initialize();
  2182. }
  2183.  
  2184. CUuencodeGopher::CUuencodeGopher( char ctype, const char* link):
  2185.     DTextGopher( ctype, link)
  2186. {
  2187.     Initialize();
  2188. }
  2189.  
  2190. DObject* CUuencodeGopher::Clone()
  2191. {
  2192.     CUuencodeGopher* aGopher= new CUuencodeGopher();
  2193.     aGopher->CopyGopher( this);
  2194.     return aGopher;
  2195. }
  2196.  
  2197. void CUuencodeGopher::DrawIcon( Nlm_RecT& area, short size)  /* override */ 
  2198. {
  2199.     gGopherIconID= kUuencodeIcon;
  2200.     gIconSize= size;
  2201.     DrawIconSub( area);
  2202. }
  2203.  
  2204. const char* CUuencodeGopher::GetKindName() 
  2205.     return "UU encoded file";
  2206. }
  2207.  
  2208. #if GOOBSOLETE
  2209. short CUuencodeGopher::GopherIt(void) // override 
  2210. {
  2211.     return DTextGopher::GopherIt();
  2212. }
  2213. #endif // GOOBSOLETE
  2214.  
  2215. #endif    // FIX_LATER
  2216.  
  2217.  
  2218.  
  2219.  
  2220.  
  2221. /** gopher+ view_names...
  2222.           case kTypeFile:
  2223.           case kTypeCSO:    view = "Text"; break;
  2224.           case kTypeGif:    view = "image/gif"; break;
  2225.           case kTypeImage:  view = "image";  break;
  2226.           case kTypeSound:  view = "audio/mulaw"; break;
  2227.           case kTypeTn3270: view = "terminal/tn3270";  break;
  2228.           case kTypeTelnet: view = "terminal/telnet";  break;
  2229.  
  2230. # An example gopherd+.conf file
  2231. #
  2232.  
  2233. # Different Languages
  2234. viewext: .txt.spanish 0 0 Text Es_ES
  2235. viewext: .txt.german 0 0 Text De_DE
  2236. viewext: .txt.french 0 0 Text Fr_FR
  2237.  
  2238.  
  2239. #data formats
  2240. #viewext: Filename extension / Advertised type-char / transfer type / +VIEWS type
  2241.  
  2242. viewext: .hqx 4 0 file/hqx
  2243.  
  2244. #
  2245. # Telnet file formats
  2246. #
  2247. viewext: .telnet 8 0 terminal/telnet
  2248. viewext: .tn3270 T 0 terminal/tn3270
  2249.  
  2250. #
  2251. # Graphics file formats
  2252. #
  2253. viewext: .gif I 9 image/gif
  2254. viewext: .pcx I 9 image/pcx
  2255. viewext: .pict I 9 image/PICT
  2256. viewext: .tiff I 9 image/TIFF
  2257. viewext: .jpg I 9 image/JPEG
  2258. viewext: .ppm I 9 image/ppm
  2259. viewext: .pgm I 9 image/pgm
  2260. viewext: .pbm I 9 image/pgm
  2261.  
  2262. #
  2263. # Sounds
  2264. #
  2265. viewext: .au s s audio/mulaw
  2266. viewext: .snd s s audio/mulaw
  2267. viewext: .wav s s audio/wave
  2268.  
  2269. #
  2270. # Movies
  2271. #
  2272. viewext: .quicktime 9 9 video/quicktime
  2273. viewext: .mpg 9 9 video/mpeg
  2274.  
  2275. #
  2276. # Binary files
  2277. #
  2278. viewext: .tar.Z 9 9 file/tar.Z
  2279. viewext: .tar 9 9 file/tar
  2280. viewext: .zip 5 9 file/PKzip
  2281. viewext: .zoo 5 9 file/Zoo
  2282. viewext: .arc 5 9 file/Arc
  2283. viewext: .lzh 5 9 file/Lharc
  2284. viewext: .exe 5 9 file/PCEXE
  2285. viewext: .mcb 9 9 file/MacBinary
  2286. viewext: .uu 9 9 file/uuencode
  2287.  
  2288.  
  2289. #
  2290. # Various forms of text
  2291. #
  2292. viewext: .ps 0 0 Text/postscript
  2293. viewext: .tex 0 0 Text/tex
  2294. viewext: .dvi 0 9 Text/dvi
  2295. viewext: .troff 0 0 Text/troff
  2296. viewext: .unicode 0 0 Text/unicode
  2297. viewext: .sjis 0 0 Text/sjis
  2298. viewext: .jis 0 0 Text/jis
  2299. viewext: .euc 0 0 Text/jis
  2300. viewext: .big5 0 0 Text/big-5
  2301. viewext: .rtf 0 0 Text/rtf
  2302. viewext: .word5 0 0 Text/MSWord5
  2303. viewext: .word4 0 0 Text/MSWord4
  2304. viewext: .mw 0 0 Text/MacWrite
  2305. viewext: .wp 0 0 Text/WordPerfect51
  2306.  
  2307. viewext: .smell 9 9 smell/funky
  2308.  
  2309. #
  2310. #
  2311. viewext: .mindex 7 mindex: Directory
  2312. viewext: .src 7 waissrc: Directory
  2313. viewext: .html h GET /h application/WWW
  2314.  
  2315.  
  2316. #
  2317. # These are for the experimental gview
  2318. #
  2319. viewext: .gview 1 1 Directory+/gview
  2320. blockext: .spot GVIEWSPOT
  2321.  
  2322. # Map files to certain blocks
  2323. #
  2324. blockext: .abstract ABSTRACT
  2325. blockext: .ask ASK
  2326.  
  2327. ****/
  2328.